/***********************************************************************************
Copy right:     Coffee Tech.
Author:         jiaoyue
Date:           2021.11.23
Description:    共享内存测试
***********************************************************************************/

#include <shmem.h>
#include <modbus.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#define errDbug printf("%s %d\n", __func__, __LINE__)

union val_t {
    int b_val;   //bool类型存储空间
    int i_val;   //整形值存储空间
    float f_val; //浮点值存储空间
};

struct std_node
{
    int key;             //唯一键值
    int type;            //数据点类型
    int dev_type;        //数据点属于哪个设备，根据网关支持的设备自行定义
    union val_t old_val; //变化上报后需要更新旧值
    union val_t new_val; //从共享内存取出最新数据，放到new_val中
    int ret;             //默认为-1，采集成功后设置为0，采集失败再置-1
};

static struct shm_param para;

int main(int argc, char *argv[])
{

    int ret = shm_init(&para, "shm_a", sizeof(struct std_node) * 100 + 4);
    if (ret < 0)
    {
        return -1;
    }
    int *addr = shm_getaddr(&para);
    struct std_node *data_ptr = NULL;
    data_ptr = addr + 1;

    if (addr == NULL)
    {
        return -1;
    }

    modbus_t *ctx = modbus_new_tcp("192.168.0.119", 7777);
    if (ctx == NULL)
    {
        errDbug;
        return -1;
    }
    if (modbus_set_slave(ctx, 1) < 0)
    {
        errDbug;
        return -1;
    }
    if (modbus_connect(ctx) < 0)
    {
        errDbug;
        return -1;
    }
    modbus_t *ctx_t = ctx; //输入寄存器
    uint16_t buf[4] = {0};

    modbus_t *ctx_r = ctx; //保持寄存器
    uint16_t bufr[1] = {0};

    modbus_t *ctx_b = ctx; //线圈寄存器
    uint8_t bufb[2] = {0};
    while (1)
    {
        modbus_read_input_registers(ctx_t, 0, 2, buf); //读取输入寄存器
        printf("温度：%d 湿度：%d", buf[0], buf[1]);
        printf("\n");
        //将读取到的数据，赋值给结构体成员
        (data_ptr + 3)->new_val.f_val = buf[0];
        (data_ptr + 4)->new_val.f_val = buf[1];

        printf("%.1f %.1f\n", (data_ptr + 3)->new_val.f_val, (data_ptr + 4)->new_val.f_val);

        modbus_read_registers(ctx_r, 0, 1, bufr); //读取保持寄存器
        printf("空调温度：%d ", bufr[0]);
        printf("\n");
        //将读到的数据，赋值给结构体成员
        (data_ptr + 6)->new_val.i_val = bufr[0];
        printf("%d \n", (data_ptr + 6)->new_val.i_val);

        modbus_read_bits(ctx_b, 0, 2, bufb); //读取线圈寄存器
        printf("空调开关：%d 灯开关：%d", bufb[0], bufb[1]);
        printf("\n");
        //将读到的开关状态，赋值给结构体中共同体成员
        (data_ptr + 5)->new_val.b_val = bufb[0];
        (data_ptr + 7)->new_val.b_val = bufb[1];
        printf("%d %d \n", (data_ptr + 6)->new_val.b_val, (data_ptr + 7)->new_val.b_val);
    }

    modbus_free(ctx);
    modbus_close(ctx);

    return 0;
}
